<template>
  <div class="fx_col" style="height: 100%">

    <!--搜索-->
    <div ref="searchDiv">
      <a-form
          ref="defSearch"
          :model="defSearch.param"
          :rules="defSearch.rules"
          :labelCol="{style: {width: '60px'}}"
          class="fx search_form_top">

        <!--搜索条件-->
        <div class="fx_row fx_wrap fx_start" style="width: calc(100%)">

          <a-form-item label="楼层" name="floor" style="width: 160px">
            <a-select v-model:value="defSearch.param.floor" placeholder="楼层">
              <a-select-option v-for="(item,index) in option.floor" :value=item.key>
                {{
                  item.text
                }}
              </a-select-option>
            </a-select>
          </a-form-item>

          <a-form-item label="区域名称" name="name" style="width: 220px">
            <a-auto-complete
                v-model:value="defSearch.param.name"
                placeholder="请输入区域名称"
                :allowClear="true"
                :options="option.autoSearchName"
                @search="(value) => { searchAsync_( 'name' ,value)}"
            >
              <template #option="item">
                <div @click="searchAsyncSelect_('name',item.name,item)" style="font-weight: bold"> {{ item.name }}</div>
              </template>
            </a-auto-complete>
          </a-form-item>
        </div>

        <!--按钮-->
        <a-form-item class="search_button_2">
          <a-button type="primary" @click.stop="search" class="font12">
            <template #icon>
              <SearchOutlined/>
            </template>
            查询
          </a-button>
          <a-button style="margin-left: 10px" @click.stop="()=>{ resetForm('defSearch'); }" class="font12">
            <template #icon>
              <UndoOutlined/>
            </template>
            重置
          </a-button>
        </a-form-item>

      </a-form>
    </div>

    <div class="fx fx_110" style="margin-top: 16px;margin-left: 16px;margin-right: 16px">

      <!--区域地图-->
      <div class="fx_col fx_110" style="border: 1px solid #F0F0F0;">

        <!--表格选项-->
        <div class="fx_center_all"
             style="height:50px;background: #FFFFFF;border-bottom: 1px solid #F0F0F0;padding-left: 16px;padding-right: 16px">
          <div style="color: rgba(0,0,0,.85);font-size: 16px;">区域地图</div>
          <div style="flex: 1 1 0"></div>
          <!--新建-->
          <a-dropdown>
            <a-button type="primary" size="small" ghost>新建</a-button>

            <template #overlay>

              <a-menu @click="optionSelect_">

                <div v-for="(item,index) in option.addArea">

                  <a-menu-item :key="item.key" :disabled="item.disabled" style="text-align: center">
                    {{ item.text }}
                  </a-menu-item>

                  <a-menu-divider v-if="index < option.addArea.length -1"/>

                </div>

              </a-menu>

            </template>

          </a-dropdown>
        </div>

        <!--canvas-->
        <div class="fx_110" ref="canvasSize" style="background: #FFFFFF">
          <canvas id="canvas"/>
        </div>

      </div>

      <!--配置信息-->
      <div class="fx_col" style="width: 360px;border: 1px solid #F0F0F0;margin-left: 20px;">

        <!--表格选项-->
        <div class="fx_row"
             style="height:50px;padding: 0 16px;background: #FFFFFF;border-bottom: 1px solid #F0F0F0; align-items: center">

          <div style="color: rgba(0,0,0,.85);font-size: 16px;">配置信息</div>

          <div style="flex: 1 1 0"></div>

          <a-tooltip placement="top">
            <template #title>
              <span>批量修改</span>
            </template>
            <SettingOutlined :style="{fontSize: '16px'}" @click="batchEdit"/>
          </a-tooltip>

          <a-divider type="vertical"/>

          <a-tooltip placement="top">
            <template #title>
              <span>保存</span>
            </template>
            <save-outlined :style="{fontSize: '16px'}" @click="edit_"/>
          </a-tooltip>

          <a-divider type="vertical"/>

          <a-popconfirm placement="bottom" ok-text="确定" cancel-text="取消" @confirm="del_">

            <template #title>
              <p>请再次确认，是否执行删除操作</p>
            </template>

            <a-tooltip placement="top">
              <template #title>
                <span>删除</span>
              </template>

              <delete-outlined :style="{fontSize: '16px'}"/>

            </a-tooltip>

          </a-popconfirm>


        </div>

        <!--区域信息表单-->
        <a-form
            ref="defForm"
            style="flex: 1 1 0;overflow-y: auto;background: #FFFFFF;"
            :model="defForm.data"
            :rules="defForm.rules"
            :layout="defForm.layout">
          <a-divider orientation="left" style="margin-top: 0">描述</a-divider>
          <!--第一行-->
          <div style="padding-left: 16px;padding-right: 16px">
            <a-form-item label="名称" name="name" style="margin-bottom:6px ;margin-top: 6px">
              <a-input v-model:value="defForm.data.name" size="small" placeholder="区域名称"/>
            </a-form-item>
            <a-form-item label="编号" name="code" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.code" size="small" placeholder="区域编号"/>
            </a-form-item>
            <a-form-item label="楼层" name="floor" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.floor" size="small" :min="1" placeholder="所属楼层"/>
            </a-form-item>
          </div>

          <a-divider orientation="left">颜色</a-divider>
          <div style="padding-left: 16px;padding-right: 16px">
            <a-form-item label="区域填充色" name="backgroundColor" style="margin-bottom:6px ">
              <div class="fx_start_center">
                <a-input this.defForm.data.config type="color" style="width: 60px"
                         v-model:value="defForm.data.config.backgroundColor"/>
                <div :style="{color:defForm.data.config.backgroundColor,fontSize:'16px',marginLeft:'8px'}">
                  {{ defForm.data.config.backgroundColor }}
                </div>
              </div>
            </a-form-item>

            <a-form-item label="区域边框色（选中）" name="selectBorderColor" style="margin-bottom:6px;">
              <div class="fx_start_center">
                <a-input this.defForm.data.config type="color" style="width: 60px"
                         v-model:value="defForm.data.config.selectBorderColor"/>
                <div :style="{color:defForm.data.config.selectBorderColor,fontSize:'16px',marginLeft:'8px'}">
                  {{ defForm.data.config.selectBorderColor }}
                </div>
              </div>
            </a-form-item>

            <a-form-item label="区域边框色（非选中）" name="borderColor" style="margin-bottom:6px;">
              <div class="fx_start_center">
                <a-input this.defForm.data.config type="color" style="width: 60px"
                         v-model:value="defForm.data.config.borderColor"/>
                <div :style="{color:defForm.data.config.borderColor,fontSize:'16px',marginLeft:'8px'}">
                  {{ defForm.data.config.borderColor }}
                </div>
              </div>
            </a-form-item>

            <a-form-item label="文字颜色" name="textColor" style="margin-bottom:6px ">
              <div class="fx_start_center">
                <a-input this.defForm.data.config type="color" style="width: 60px"
                         v-model:value="defForm.data.config.textColor"/>
                <div :style="{color:defForm.data.config.textColor,fontSize:'16px',marginLeft:'8px'}">
                  {{ defForm.data.config.textColor }}
                </div>
              </div>
            </a-form-item>
          </div>


          <a-divider orientation="left" style="margin-top: 0">大小</a-divider>
          <div style="padding-left: 16px;padding-right: 16px">

            <a-form-item label="边框宽度" name="borderSize" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.borderSize" size="small" placeholder="边框宽度"/>
            </a-form-item>

            <a-form-item label="文字大小" name="textSize" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.textSize" size="small" placeholder="文字大小"/>
            </a-form-item>
            <a-form-item label="文字宽度" name="textWidth" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.textWidth" size="small" placeholder="文字宽度"/>
            </a-form-item>
          </div>

          <a-divider orientation="left" style="margin-top: 0">位置</a-divider>
          <div style="padding-left: 16px;padding-right: 16px">

            <a-form-item label="图层排序" name="graph_sort" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.graph_sort" size="small" placeholder="图层排序（默认100）"/>
            </a-form-item>

            <a-form-item label="文字X坐标" name="textX" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.textX" size="small" placeholder="文字X坐标"/>
            </a-form-item>

            <a-form-item label="文字Y坐标" name="textY" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.textY" size="small" placeholder="文字Y坐标"/>
            </a-form-item>

            <a-form-item label="文字X轴偏移量" name="textXOffset" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.textXOffset" size="small" placeholder="文字X轴偏移量"/>
            </a-form-item>

            <a-form-item label="文字Y轴偏移量" name="textYOffset" style="margin-bottom:6px ">
              <a-input v-model:value="defForm.data.config.textYOffset" size="small" placeholder="文字Y轴偏移量"/>
            </a-form-item>
          </div>

          <a-divider orientation="left" style="margin-top: 0">状态</a-divider>
          <div style="padding-left: 16px;padding-right: 16px">
            <a-form-item label="区域状态" style="margin-bottom:6px ">
              <a-switch v-model:checked="defForm.data.config.showArea"
                        checked-children="可见"
                        un-checked-children="隐藏"
              />
              <a-switch v-model:checked="defForm.data.config.isSelect" style="margin-left: 5px"
                        checked-children="可选"
                        un-checked-children="不可选"
              />
            </a-form-item>

            <a-form-item label="文字状态" name="showText" style="margin-bottom:6px ">
              <a-switch v-model:checked="defForm.data.config.showText"
                        checked-children="可见"
                        un-checked-children="隐藏"
              />
            </a-form-item>
            <a-form-item label="边框状态" name="showBorder" style="margin-bottom:6px ">
              <a-switch v-model:checked="defForm.data.config.showBorder"
                        checked-children="可见"
                        un-checked-children="隐藏"
              />
            </a-form-item>

            <a-form-item label="图层置顶" name="isTop" style="margin-bottom:6px ">
              <a-switch v-model:checked="defForm.data.config.isTop"
                        checked-children="开启"
                        un-checked-children="关闭"
              />
            </a-form-item>
            <a-form-item label="图层置底" name="isBottom" style="margin-bottom:6px ">
              <a-switch v-model:checked="defForm.data.config.isBottom"
                        checked-children="开启"
                        un-checked-children="关闭"
              />
            </a-form-item>
          </div>


          <a-divider orientation="left" style="margin-top: 0">区域坐标</a-divider>
          <div style="padding-left: 16px;padding-right: 16px">
            <!--动态表单循环-->
            <a-space align="baseline" v-for="(item, index) in defForm.data.xy" style="display: flex; ">

              <a-form-item label="X"
                           :name="['xy',index, 'x']"
                           :rules="{required: true,message: '必填项',trigger: 'blur'}">
                <a-input v-model:value="item.x"></a-input>
              </a-form-item>

              <a-form-item label="Y"
                           :name="['xy',index, 'y']"
                           :rules="{required: true,message: '必填项',trigger: 'blur'}">
                <a-input v-model:value="item.y"></a-input>
              </a-form-item>

              <!--删除-->
              <MinusCircleOutlined @click="removeXyItem_(defForm.data.xy,item)" class="_hover_color_red_"/>
            </a-space>

            <!--添加-->
            <a-form-item>
              <a-button type="dashed" block @click="addXyItem_(defForm.data.xy)">
                <PlusOutlined/>
                添加
              </a-button>
            </a-form-item>
          </div>
        </a-form>

      </div>

    </div>

    <!--新增Dialog-->
    <a-modal
        title="新增区域"
        width="70%"
        v-model:visible="option.addDef"
        :destroyOnClose="true"
        :maskClosable="false">

      <!--新增表单-->
      <a-form
          ref="addForm"
          :model="defForm.data"
          :rules="defForm.rules"

      >

        <a-form-item label="区域名称" name="name">
          <a-input v-model:value="defForm.data.name" placeholder="区域名称"/>
        </a-form-item>

        <a-form-item label="所在楼层" name="floor">
          <a-input v-model:value="defForm.data.floor" placeholder="所在楼层"/>
        </a-form-item>

        <a-form-item label="区域坐标">

          <!--动态表单循环-->
          <a-space align="baseline" v-for="(item, index) in defForm.data.xy" style="display: flex; ">

            <a-form-item label="X"
                         :name="['xy',index, 'x']"
                         :rules="{required: true,message: '必填项',trigger: 'blur'}"
            >
              <a-input v-model:value="item.x"></a-input>
            </a-form-item>

            <a-form-item label="Y"
                         :name="['xy',index, 'y']"
                         :rules="{required: true,message: '必填项',trigger: 'blur'}"
            >
              <a-input v-model:value="item.y"></a-input>
            </a-form-item>
            <!--删除-->
            <MinusCircleOutlined @click="removeXyItem_(defForm.data.xy,item)" class="_hover_color_red_"/>
          </a-space>

          <!--添加-->
          <a-form-item>
            <a-button type="dashed" block @click="addXyItem_(defForm.data.xy)">
              <PlusOutlined/>
              添加
            </a-button>
          </a-form-item>

        </a-form-item>

      </a-form>

      <!--底部按钮-->
      <template #footer>
        <a-button @click="option.addDef = false">取消</a-button>
        <a-button class="" @click="()=>{resetForm_('addForm')}">重置</a-button>
        <a-button class="" type="primary" @click="add_()">保存</a-button>
      </template>

    </a-modal>

    <!--批量设置-->
    <a-modal
        title="批量设置"
        width="70%"
        v-model:visible="option.openBatchEdit"
        :destroyOnClose="true"
        :maskClosable="false">

      <a-form
          ref="defForm"
          style="flex: 1 1 0;overflow-y: auto;background: #FFFFFF;"
          :model="defForm.data"
          :rules="defForm.rules"
          :layout="defForm.layout"

      >

        <a-divider orientation="left">颜色</a-divider>
        <div style="padding-left: 16px;padding-right: 16px">
          <a-form-item label="区域填充色" name="backgroundColor" style="margin-bottom:6px ">
            <div class="fx_start_center">
              <a-input this.defForm.data.config type="color" style="width: 60px"
                       v-model:value="defForm.data.config.backgroundColor"/>
              <div :style="{color:defForm.data.config.backgroundColor,fontSize:'16px',marginLeft:'8px'}">
                {{ defForm.data.config.backgroundColor }}
              </div>
            </div>
          </a-form-item>

          <a-form-item label="区域边框色（选中）" name="selectBorderColor" style="margin-bottom:6px;">
            <div class="fx_start_center">
              <a-input this.defForm.data.config type="color" style="width: 60px"
                       v-model:value="defForm.data.config.selectBorderColor"/>
              <div :style="{color:defForm.data.config.selectBorderColor,fontSize:'16px',marginLeft:'8px'}">
                {{ defForm.data.config.selectBorderColor }}
              </div>
            </div>
          </a-form-item>

          <a-form-item label="区域边框色（非选中）" name="borderColor" style="margin-bottom:6px;">
            <div class="fx_start_center">
              <a-input this.defForm.data.config type="color" style="width: 60px"
                       v-model:value="defForm.data.config.borderColor"/>
              <div :style="{color:defForm.data.config.borderColor,fontSize:'16px',marginLeft:'8px'}">
                {{ defForm.data.config.borderColor }}
              </div>
            </div>
          </a-form-item>

          <a-form-item label="文字颜色" name="textColor" style="margin-bottom:6px ">
            <div class="fx_start_center">
              <a-input this.defForm.data.config type="color" style="width: 60px"
                       v-model:value="defForm.data.config.textColor"/>
              <div :style="{color:defForm.data.config.textColor,fontSize:'16px',marginLeft:'8px'}">
                {{ defForm.data.config.textColor }}
              </div>
            </div>
          </a-form-item>
        </div>

        <a-divider orientation="left" style="margin-top: 0">大小</a-divider>
        <div style="padding-left: 16px;padding-right: 16px">

          <a-form-item label="边框宽度" name="borderSize" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.borderSize" size="small" placeholder="边框宽度"/>
          </a-form-item>

          <a-form-item label="文字大小" name="textSize" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.textSize" size="small" placeholder="文字大小"/>
          </a-form-item>
          <a-form-item label="文字宽度" name="textWidth" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.textWidth" size="small" placeholder="文字宽度"/>
          </a-form-item>
        </div>

        <a-divider orientation="left" style="margin-top: 0">位置</a-divider>
        <div style="padding-left: 16px;padding-right: 16px">

          <a-form-item label="图层排序" name="graph_sort" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.graph_sort" size="small" placeholder="图层排序（默认100）"/>
          </a-form-item>

          <a-form-item label="文字X坐标" name="textX" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.textX" size="small" placeholder="文字X坐标"/>
          </a-form-item>

          <a-form-item label="文字Y坐标" name="textY" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.textY" size="small" placeholder="文字Y坐标"/>
          </a-form-item>

          <a-form-item label="文字X轴偏移量" name="textXOffset" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.textXOffset" size="small" placeholder="文字X轴偏移量"/>
          </a-form-item>

          <a-form-item label="文字Y轴偏移量" name="textYOffset" style="margin-bottom:6px ">
            <a-input v-model:value="defForm.data.config.textYOffset" size="small" placeholder="文字Y轴偏移量"/>
          </a-form-item>
        </div>

        <a-divider orientation="left" style="margin-top: 0">状态</a-divider>
        <div style="padding-left: 16px;padding-right: 16px">
          <a-form-item label="区域状态" style="margin-bottom:6px ">
            <a-switch v-model:checked="defForm.data.config.showArea"
                      checked-children="可见"
                      un-checked-children="隐藏"
            />
            <a-switch v-model:checked="defForm.data.config.isSelect" style="margin-left: 5px"
                      checked-children="可选"
                      un-checked-children="不可选"
            />
          </a-form-item>
          <a-form-item label="文字状态" name="showText" style="margin-bottom:6px ">
            <a-switch v-model:checked="defForm.data.config.showText"
                      checked-children="可见"
                      un-checked-children="隐藏"
            />
          </a-form-item>
          <a-form-item label="边框状态" name="showBorder" style="margin-bottom:6px ">
            <a-switch v-model:checked="defForm.data.config.showBorder"
                      checked-children="可见"
                      un-checked-children="隐藏"
            />
          </a-form-item>
        </div>

      </a-form>

      <!--底部按钮-->
      <template #footer>
        <a-button @click="option.openBatchEdit = false">取消</a-button>
        <a-button class="" @click="()=>{resetForm_('addForm')}">重置</a-button>
        <a-button class="" type="primary" @click="add_()">保存</a-button>
      </template>

    </a-modal>

  </div>
</template>

<script lang="ts">
import {useUserStore} from "@/common/store/modules/user";
import {copyObj, getCenterPosition, toJsonObject} from "@/common/util/kit";
import {requiredBlur} from "@/common/util/validate";
import {fabric} from 'fabric'

export default {
  mounted() {
    this.intiCanvas();
    // fabric.Image.fromURL(logo, img => {
    //   img.selectable = true
    //   img.hasControls = false
    //   img.lockMovementX = true
    //   img.lockMovementY = true
    //   this.canvas.add(img) // 将图片加入到画布
    //   this.resizeCanvas()
    // })
    this.queryAreaMap()

    //监控窗口大小变更
    window.onresize = () => {
      this.resizeCanvas()
    }

    //监控菜单关闭
    // this.$watch(() => $store.state.closeLeftSider, () => {
    //   setTimeout(() => {
    //     this.resizeCanvas()
    //   }, 300)
    // })


    //监控菜单关闭
    // this.$watch(() => this.defForm.data.config.borderColor, () => {
    //console.log(this.defForm.data.config.borderColor)
    // })


    //鼠标滑动监听
    // this.$refs.canvasSize.$el.onmousewheel = (event) => {
    //   let canvas = this.canvas
    //   let scale = this.canvasConfig.scale
    //   let max = this.canvasConfig.maxScale
    //   let min = this.canvasConfig.minScale
    //   ////console.log(zoomNum)
    //   //console.log(event.deltaY)
    //   let zoom = (event.deltaY > 0 ? -scale : scale) + canvas.getZoom();
    //   //console.log(zoom)
    //   zoom = Math.max(min, zoom); //最小为原来的1/10
    //   zoom = Math.min(max, zoom); //最大是原来的3倍
    //   const zoomPoint = new fabric.Point(0, 0)
    //   this.canvas.zoomToPoint(zoomPoint, zoom)
    // };

  },
  //数据
  data() {
    return {
      //store
      userStore: useUserStore(),
      //选项
      option: {
        openBatchEdit: false,
        addDef: false,
        autoSearchName: [],
        floor: [
          {key: '1', text: '1'},
          {key: '2', text: '2'},
          {key: '3', text: '3'},
        ],
        areaType: [
          {key: '0', text: '普通区域'},
          {key: '1', text: '商家'},
          {key: '2', text: '路段'},
        ],
        addArea: [
          {key: '1', text: '表单'},
          {key: '2', text: '点位'},
          {key: '4', text: '圆形'},
          {key: '5', text: '四边形'},
          {key: '3', text: '自由绘制'},
        ]
      },

      //搜索表单（默认）
      defSearch: {
        param: {
          floor: '1',
          name: undefined,
        },
        rules: {},
      },

      //表单（默认）
      defForm: {
        //实际表单数据
        data: {},
        initData:
            {
              config: {
                "borderColor": "#000000",
                "backgroundColor": "#000000",
                "textColor": "#000000",
                "selectBorderColor": "#000000",
                "textSize": 0,
                "showText": true,
                "borderSize": 0,
                "showBorder": true,
                "showArea": true,
                "isBottom": false,
                "isTop": false,
                "textX": "0",
                "text": "",
                "textY": "0",
                "fontWidth": "0",
                "textXOffset": "0",
                "textYOffset": "0"
              },
            },
        rules: {
          api_name: [requiredBlur],
        },
      },
      canvas: null,
      canvasConfig: {
        mouseIsDown: false,
        background: '#E4E6E3',
        defaultZoom: 1,
      },
      //闪烁动画定时器
      flickerTimer: null,
    }
  },
  //方法
  methods: {
    onColorChange(e, key) {
      console.log(typeof this.defForm.data.config)
      console.log(e.target.value)
      this.defForm.data.config[key] = e.target.value
      console.log(this.defForm.data.config[key])

    },
    removeXyItem_(xy, item) {
      let index = xy.indexOf(item);
      if (index != -1) {
        xy.splice(index, 1);
      }
    },
    addXyItem_(xy) {
      xy.push({
        x: undefined,
        y: undefined,
      });
    },
    mouseenter() {
      document.body.style.overflow = 'hidden';
    },
    mouseleave() {
      document.body.style.overflow = '';
    },

    //查询：页面数据
    queryPage() {
      if (!this.search.def.name && !this.search.def.type) {
        this.$message.warn("操作失败：请先输入名称", 2)
        return;
      }

      let param = {
        ...this.search.def
      }

      this.$http.post('/position/area/map/list', param).then((res) => {
        if (res.status) {
          if (res.data.length == 0) {
            this.$message.success("未查询到任何信息")
            return;
          }
          //
          let ids = []
          res.data.filter(item => {
            ids.push(item.id)
          })

          //筛选
          let objs = this.canvas.getObjects()
          objs.filter(target => {
            if (ids.indexOf(target.id) != -1) {
              this.flicker(target, 600, 5, "#d00d0d", target.fill)
            }
          })

          this.$message.success("查询成功，已高亮展示")

        } else {
          this.$message.warning(res.message)
        }
      })
    },
    //闪烁
    /**
     * TODO 抽成工具类
     * @param target 画布对象
     * @param time 变色持续时间，毫秒
     * @param cycleCount 循环次数
     * @param flickerFill 闪烁时颜色
     * @param revertFill 还原颜色
     */
    flicker(graphObj, time, cycleCount, flickerFill, revertFill) {
      if (this.flickerTimer == null) {
        let canvas = this.canvas
        let count = 1;
        //闪烁
        this.flickerTimer = setInterval(() => {
          graphObj.set('fill', revertFill);

          graphObj.animate('fill', flickerFill, {
            onChange: canvas.renderAll.bind(canvas),
            onComplete: () => {
              count += 1;
              if (count >= cycleCount) {
                clearInterval(this.flickerTimer)
                graphObj.set('fill', revertFill);
                canvas.renderAll()
                this.flickerTimer = null
              }
            },
            duration: time
          });
        }, time)
      }
    },
    optionSelect_(item) {
      //
      if (item.key == 1) {
        this.option.addDef = true
        this.defForm.data = JSON.parse(JSON.stringify(this.defForm.resetData))
      }

    },
    //canvas：查询区域信息
    add_() {
      this.$refs.addForm
          .validate()
          .then(() => {
            this.$http.post("/position/area/map/add", this.defForm.data).then((res) => {
              if (res.status) {
                this.$message.success(res.message)
                this.option.addDef = false
              } else {
                this.$message.warning(res.message)
              }
            })
          })
          .catch(error => {
            this.$message.warning("存在错误，请检查表单填写情况。", 2)
          });
    },
    //批量设置
    batchEdit() {
      this.defForm.data = copyObj(this.defForm.initData)
      this.option.openBatchEdit = true;
    },
    //操作：修改信息
    edit_() {
      this.$refs.defForm
          .validate()
          .then(() => {
            this.$http.post("/position/area/map/edit", this.defForm.data).then(async (res) => {
              if (res.status) {
                this.$message.success(res.message)
                this.queryAreaMap()

              } else {
                this.$message.warning(res.message)
              }
            })
          })
          .catch(error => {
            this.$message.warning("存在错误，请检查表单填写情况。", 2)
          });
    },
    //操作：删除信息
    del_() {
      if (!this.defForm.data || !this.defForm.data.id) {
        this.$message.warn("请先选择一个区域")
        return;
      }

      this.$http.post("/position/area/map/del", {ids: [this.defForm.data.id]}).then((res) => {
        if (res.status) {
          this.$message.success(res.message)
          this.defForm.data = {}
          this.queryAreaMap()
        } else {
          this.$message.warning(res.message)
        }
      })
    },
    async queryAreaMap() {
      this.canvas.clear()
      this.canvas.renderAll()
      return this.$http.post('/position/area/map/list', this.defSearch.param).then((res) => {
        if (res.status) {

          let maps = []
          let area = []
          let store = []
          let road = []

          // 区域类型(0普通区域；1商家；2路段)
          res.data.filter(item => {
            if (item.type == 0) {
              area.push(item)
            }
            if (item.type == 1) {
              store.push(item)
            }
            if (item.type == 2) {
              road.push(item)
            }
          })

          // ////console.log("maps", maps)
          // ////console.log("area", area)
          // ////console.log("store", store)
          // ////console.log("road", road)
          // ////console.log("maps", maps)
          maps.push(...area)
          maps.push(...store)
          maps.push(...road)
          this.drawMap(maps)
          this.resizeCanvas()
        } else {
          this.$message.warning(res.message)
        }
      })
    },

    //canvas：绘制区域
    drawMap(datas) {
      for (let i = 0; i < datas.length; i++) {

        let data = datas[i]
        ////console.log(data)
        let config = JSON.parse(data.config)
        let xyArray = JSON.parse(data.area_xy)

        //画区域
        let graphPath
        if (config && config.showArea) {

          //起点
          let M_X = parseFloat(xyArray[0].x)
          let M_Y = parseFloat(xyArray[0].y)
          let pathStr = 'M ' + M_X + ' ' + (M_Y * -1)
          //循环追加点位
          for (let i = 1; i < xyArray.length; i++) {
            let L_X = parseFloat(xyArray[i].x)
            let L_Y = parseFloat(xyArray[i].y)
            pathStr += ' L ' + L_X + ' ' + (L_Y * -1)
          }
          //终止
          pathStr += ' z'

          //绘制
          graphPath = new fabric.Path(pathStr, {
            fill: config.backgroundColor,
            selectable: true,
            hasControls: false,
            lockMovementX: true,
            lockMovementY: true,
            //自定义属性
            data: data,
          })

          //边框
          if (config.showBorder) {
            //边框颜色
            if (config.borderColor) {
              graphPath.stroke = config.borderColor
            }
            //边框宽度
            if (config.borderSize) {
              graphPath.strokeWidth = parseFloat(config.borderSize)
            }
          }

          this.canvas.add(graphPath)

          //向上到顶层
          if (config.isTop) {
            this.canvas.bringToFront(graphPath)
          }

          //向下到底层
          if (config.isBottom) {
            this.canvas.sendToBack(graphPath)
          }

        }

        //加文字
        if (config && config.showArea && config.showText) {
          // if (0==1) {
          ////console.log(5)

          //计算中心坐标
          let pathS = []
          for (let k = 0; k < graphPath.path.length - 1; k++) {
            let path_ = graphPath.path[k]
            pathS.push({x: path_[1], y: path_[2]})
          }
          let centerPosition = getCenterPosition(pathS)

          //绘制
          let graphText = new fabric.Textbox(data.name, {
            fontSize: config.textSize * 1,
            hasControls: false,
            lockMovementX: true,
            lockMovementY: true,
            selectable: false,
            //自定义属性
            data: data,
          })

          //中心坐标
          graphText.top = centerPosition.centerY - graphText.height
          graphText.left = centerPosition.centerX - (graphText.width / 2)

          //文字宽度
          if (config.textWidth) {
            graphText.width = parseFloat(config.textWidth)
            graphText.splitByGrapheme = true
          }

          //文字颜色
          if (config.textColor) {
            graphText.fill = config.textColor
          }

          //坐标
          if (config.textX) {
            graphText.left = parseFloat(config.textX)
          }
          if (config.textY) {
            graphText.top = parseFloat(config.textY)
          }

          //偏移量
          if (config.textXOffset) {
            graphText.left = graphText.left + parseFloat(config.textXOffset)
          }
          if (config.textYOffset) {
            graphText.top = graphText.top + (parseFloat(config.textYOffset) * -1)
          }

          this.canvas.add(graphText)
        }
      }
    },

    //区域信息
    areaInfo(event) {
      let data = event.target.data
      // //console.log("【data】", data)
      this.defForm.data = copyObj(data)
      this.defForm.data.xy = toJsonObject(event.target.data.area_xy)
      this.defForm.data.config = toJsonObject(data.config)
    },

    //查询：异步搜索完成查询
    searchAsync_(key, value) {
      ////console.log("searchAsync, key=" + key + ' , value=' + value)
      this.$http.post('/position/area/map/searchInput', {[key]: value}).then(res => {
        this.option.autoSearchName = res.data
      })
    },

    //查询：异步搜索点击选择事件
    searchAsyncSelect_(key, value, item) {
      //console.log("searchAsyncSelect_, key " + key)
      //console.log("searchAsyncSelect_, value " + value)
      //console.log("searchAsyncSelect_, item " + item)
      this.search.def.name = value
    },

    //重置：查询表单重置
    resetForm_(formName) {
      if (this.$refs[formName]) {
        this.$refs[formName].resetFields()
      }
    },
    //
    fullScreen() {
    },
    //canvas：初始化
    intiCanvas() {
      this.canvas = new fabric.Canvas('canvas', {
        selection: false
      })
      this.canvas.preserveObjectStacking = true

      // 鼠标按下事件
      this.canvas.on('mouse:down', (event) => {
        this.areaInfo(event)
        this.canvasConfig.mouseIsDown = true
        // //console.log("canvas:mouse:down", event)
        ////console.log("event.target", event.target)
        // this.flicker(true, event.target)
      })

      // 鼠标抬起事件
      this.canvas.on('mouse:up', (event) => {
        // //console.log("canvas:mouse:up", event)
        this.canvasConfig.mouseIsDown = false
      })

      //移动画布事件
      this.canvas.on('mouse:move', (event) => {
        // //console.log("event", event)
        // //console.log("event.e", event.e)
        // //console.log("mouseIsDown", this.canvasConfig.mouseIsDown)
        if (this.canvasConfig.mouseIsDown && event && event.e) {
          let delta = new fabric.Point(event.e.movementX, event.e.movementY)
          this.canvas.relativePan(delta)
        }
      })

      // 监听鼠标滚轮事件
      this.canvas.on('mouse:wheel', opt => {
        // 滚轮向上滚一下是 -100，向下滚一下是 100
        let delta = opt.e.deltaY
        // 获取画布当前缩放值
        let zoom = this.canvas.getZoom()

        zoom -= 0.005 * delta
        if (zoom > 20) zoom = 20
        if (zoom < 1) zoom = 1
        // 设置画布缩放比例
        this.canvas.zoomToPoint(
            {
              x: opt.e.offsetX,
              y: opt.e.offsetY
            },
            zoom
        )
      })

    },
    //canvas：缩放
    setZoom(zoomNum) {
      let zoom = zoomNum + (zoomNum === 0 ? 1 : this.canvas.getZoom())
      zoom = Math.max(this.canvasConfig.defaultZoom, zoom) // 最小为原来
      zoom = Math.min(3, zoom) // 最大是原来的3倍
      const zoomPoint = new fabric.Point(0, 0)
      this.canvas.zoomToPoint(zoomPoint, zoom)
    },

    //canvas：布局大小变更
    resizeCanvas() {
      let canvas = this.canvas;
      canvas.setWidth(0)
      canvas.setHeight(0)
      //
      canvas.setWidth(this.$refs.canvasSize.offsetWidth)
      canvas.setHeight(this.$refs.canvasSize.offsetHeight)
      // 计算
      const [minX, minY, maxX, maxY] = this.calcBorder()
      // ////console.log("minX",minX)
      // ////console.log("minY",minY)
      // ////console.log("maxX",maxX)
      // ////console.log("maxY",maxY)

      // 平移
      const panX = (maxX - minX - canvas.width) / 2 + minX
      const panY = (maxY - minY - canvas.height) / 2 + minY
      canvas.absolutePan({x: panX, y: panY})

      //缩放
      let zoom = Math.min(canvas.width / (maxX - minX), canvas.height / (maxY - minY))

      //计算缩放中心
      let zoomPoint = new fabric.Point(canvas.width / 2, canvas.height / 2)

      //开始缩放
      canvas.zoomToPoint(zoomPoint, zoom)

      //
      this.canvasConfig.defaultZoom = zoom
      //////console.log(this.defaultZoom)
    },
    //搜索
    search() {
      this.$refs.defSearch.validate().then(() => {
        this.queryAreaMap()
      }).catch(error => {
        this.$message.warning("存在错误，请检查表单填写情况。", 2)
      });
    },
    //canvas：计算布局大小变更宽高
    calcBorder() {
      let canvas = this.canvas
      //先还原缩放比例与位置
      canvas.setZoom(1)
      canvas.absolutePan({x: 0, y: 0})

      //遍历所有显示对象，获取最小坐标，最大坐标
      let objects_ = canvas.getObjects()
      let objects = []
      objects_.filter(e => {
        if (e.visible) {
          objects.push(e)
        }
      })

      // ////console.log("objects", objects)
      let minX = 0
      let minY = 0
      let maxX = canvas.width
      let maxY = canvas.height
      // ////console.log("minX",minX)
      // ////console.log("minY",minY)
      // ////console.log("maxX",maxX)
      // ////console.log("maxY",maxY)
      if (objects.length > 0) {
        let rect = objects[0].getBoundingRect()
        minX = rect.left
        minY = rect.top
        maxX = rect.left + rect.width
        maxY = rect.top + rect.height
        for (let i = 1; i < objects.length; i++) {
          rect = objects[i].getBoundingRect()
          minX = Math.min(minX, rect.left)
          minY = Math.min(minY, rect.top)
          maxX = Math.max(maxX, rect.left + rect.width)
          maxY = Math.max(maxY, rect.top + rect.height)
        }
      }
      return [minX, minY, maxX, maxY]
    },
    //重置表单（还原）
    resetForm(formName) {
      let form = this.$refs[formName]
      if (form) {
        form.resetFields()
      }
    },
  }
}
</script>

<style scoped lang="less">

::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, .12);
  border-radius: 3px;
  -webkit-box-shadow: inset 0 0 5px rgb(0 21 41 / 5%);
}

::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, .06);
}
</style>
